package com.james.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.james.anno.Log;
import com.james.domain.Food;
import com.james.domain.Order;
import com.james.feign.UserServiceFeign;
import com.james.service.OrderService;
import com.james.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @ClassName: OrderController
 * @Author: JamesWang
 * @Date: 2021/4/22 13:42
 * @Description:
 * @Version:1.0
 */
@RestController
@RequestMapping("order")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserServiceFeign userServiceFeign;

    /**
     * 每次点餐限一种食物，数量不限，
     * 点餐需要记录日志，
     * 发送微信公众号消息，
     * 同时增加用户积分（积分为消费的总金额）
     * 1.查询用户表 获得用户对象
     * 2.查询food表得到菜品对象
     * 3.计算金额
     * 4.新增订单表
     *
     * @return
     */
    @Log(operation = "下订单")
    @PostMapping("doOrder")
    public ResponseEntity<Map<String, Object>> doOrder(Food food) {

        orderService.doOrder(food);

        Map<String, Object> map = new HashMap<>(8);
        map.put("code", 200);
        map.put("msg", "下单成功");
        return ResponseEntity.ok(map);
    }

    /**
     * 用户分页查询订单，同时需要看到当前总积分
     *
     * @param page
     * @return
     */
    @GetMapping("page")
    public ResponseEntity<Map<String, Object>> pageInfo(Page<Order> page) {

        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        Page<Order> pageInfo = orderService.page(page, new LambdaQueryWrapper<Order>()
                .eq(Order::getUserId, userId));
//        User user = userService.getById(userId);
//        Integer score = user.getScore();
        Integer score = (Integer) userServiceFeign.getScore().get("data");

        Map<String, Object> data = new HashMap<>(8);
        data.put("score", score);
        data.put("data", pageInfo.getRecords());

        Map<String, Object> map = new HashMap<>(8);
        map.put("code", 200);
        map.put("msg", "ok");
        map.put("data", data);
        return ResponseEntity.ok(map);

    }

    /**
     * 用户取消订单，同时需要扣减对应积分
     *
     * @param orderId
     * @return
     */
    @PostMapping("cancel")
    @Transactional
    public ResponseEntity<Map<String, Object>> cancelOrder(Long orderId) {

        orderService.cancelOrder(orderId);

        Map<String, Object> map = new HashMap<>(8);
        map.put("code", 200);
        map.put("msg", "订单取消成功");
        return ResponseEntity.ok(map);
    }

    public static void main(String[] args) {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Object o = new Object();
        synchronized (o) {
            System.out.println("wo");
            try {
                o.wait(1000L);
            } catch (InterruptedException e) {

            }
        }

        HashMap<String, Object> map = new HashMap<>();
        MyThread myThread = new MyThread();
        try {
            myThread.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                3,
                10,
                20,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(100),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }


    static class MyThread implements Callable<Void> {

        /**
         * Computes a result, or throws an exception if unable to do so.
         *
         * @return computed result
         * @throws Exception if unable to compute a result
         */
        @Override
        public Void call() throws Exception {
            System.out.println("wo");
            throw new RuntimeException();
        }
    }
}
